﻿


using Grpc.Core;
using IotContract.Configs;
using IotContract.Dtos.Clients;
using IotContract.Dtos.Servers;
using IotContract.Dtos.Servers.Pushs;
using IotContract.Enums;
using IotContract.Grpcs;
using IotContract.Interfaces;
using IotContract.Models;
using IotContract.Models.Clients;
using IotContract.Models.Clients.Hks;
using IotContract.Models.Process;
using IotContract.Models.Webs;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XT.Common.Config;
using XT.Common.Extensions;
using XT.Common.Services;
using XT.Grpc.Services;

namespace IotClientService.Grpcs;
/// <summary>
/// Grpc数据交互服务
/// </summary>
public class ClientConnectDataService : IConnectDataService
{
    private IConnectGrpcService _connectGrpcService;
    private IRemoteGrpcService _remoteGrpcService;
    private GrpcChannelService _grpcChannelService;
    private ILogService _logService;

    public AddressConfig AddressConfig { get; set; }

    public ClientConnectDataService(GrpcChannelService grpcChannelService,ILogService logService)
    {
        _grpcChannelService = grpcChannelService;
        _logService= logService;
    }

    #region 连接Grpc服务
    /// <summary>
    /// 连接到rpc
    /// </summary>
    /// <returns></returns>
    private async Task ConnectGrpcServer()
    {
        if (_connectGrpcService == null || !_grpcChannelService.IsConnect)
        {
            try
            {
                var url = AppSettings.GetValue("ServerAddress");
                _connectGrpcService = await _grpcChannelService.CreateGrpcService<IConnectGrpcService>(url);
                var address = await _connectGrpcService.GetUrlAddress();
                if (address.IsSuccess)
                {
                    AddressConfig = address.Data;
                }
            }
            catch(Exception)
            {
                // 连接失败，等待3s
                await Task.Delay(3000);
            }
        }


    }
    /// <summary>
    /// 连接rpc Data,通过grpc服务来获取远程数据，弃用，之间通过http请求，减轻服务端压力
    /// </summary>
    /// <returns></returns>
    private async Task ConnectRemoteServer()
    {
        if (_remoteGrpcService == null || !_grpcChannelService.IsConnect)
        {
            var url = AppSettings.GetValue("ServerAddress");
            _remoteGrpcService = await _grpcChannelService.CreateGrpcService<IRemoteGrpcService>(url);
            
        }

    }

    #endregion
    /// <summary>
    /// 添加程序
    /// </summary>
    /// <param name="clientConnect"></param>
    /// <returns></returns>
    public async Task<(IotProgramDto, string)> AddProgram(ClientConnectCommand clientConnect)
    {
        await ConnectGrpcServer();
        var result = await new Func<Task<GrpcReturn<ClientStatusReturn>>>(() => _connectGrpcService.ConnectCommand(clientConnect)).ProtectFunc();
        if (result.Item2.IsNullOrEmpty() && result.Item1.IsSuccess)
        {
            return (new IotProgramDto
            {
                Id = result.Item1.Data.ProgramId,
                Name = result.Item1.Data.Name

            }, "");
        }
        else
        {
            return (new IotProgramDto(), result.Item2 ?? result.Item1.Msg);
        }

    }

    /// <summary>
    /// 提交程序状态
    /// </summary>
    /// <param name="clientStatus"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<int> CommitStatus(ClientStatusCommand clientStatus)
    {
        await ConnectGrpcServer();
        var result = await new Func<Task<GrpcReturn<ClientStatusReturn>>>(() => _connectGrpcService.StatusCommand(clientStatus)).ProtectFunc();
        if (result.Item2.IsNullOrEmpty() && result.Item1.IsSuccess)
        {
            return result.Item1.Data.IsEnable;
        }
        else
        {
            return 0;
        }
    }
    /// <summary>
    /// 推送设备数据
    /// </summary>
    /// <param name="equips"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<List<OperationWriteCommand>> PushEquips<T>(List<T> equips) where T:IPushEquip
    {
        await ConnectGrpcServer();

        
        if (equips==null || equips.Count == 0 || _grpcChannelService.IsConnect == false)
        {
            return new List<OperationWriteCommand>();
        }
        else
        {
            try
            {
                List<OperationWriteCommand> commands = new List<OperationWriteCommand>();
                var protobufType = equips.FirstOrDefault().ProtobufType;
                
                commands = await _connectGrpcService.PushEquips(equips.ConvertAll(x=>x as PushEquipDto));

                if (commands.Count > 0)
                {
                    return commands;
                }
                return commands;
            }
            catch(Exception ex)
            {
               _logService.LogError($"push error,{ex.Message}");
                return new List<OperationWriteCommand>();
            }

        }
    }

    /// <summary>
    /// 获取设备
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<(List<IotEquipDto>, string)> GetEquips(ClientRequestCommand command)
    {
        try
        {
            await ConnectGrpcServer();
            var result = await _connectGrpcService.RequestEquipsCommand(command);
            return (result.Data, result.Msg);
        }
        catch (Exception ex)
        {
            return (null, ex.Message);
        }
    }
    /// <summary>
    /// 获取点位信息
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<(List<EquipTagDto>, string)> GetEquipTags(ClientRequestCommand command)
    {
        try
        {
            await ConnectGrpcServer();
            var result = await _connectGrpcService.RequestTagsCommand(command);
            return (result.Data, result.Msg);
        }
        catch (Exception ex)
        {
            return (null, ex.Message);
        }
    }
   /// <summary>
   /// 读取控制指令
   /// </summary>
   /// <param name="programId"></param>
   /// <param name="token"></param>
   /// <returns></returns>
    public async IAsyncEnumerable<ClientControlCommand> ReadControl(long programId,CancellationToken token)
    {
      
            var options = new CallOptions(cancellationToken: token);

     
            await ConnectGrpcServer();
       
            await foreach(var data in   _connectGrpcService.ReadControlCommand(new ClientControlCommand
            {
                ProgramId = programId
            },new ProtoBuf.Grpc.CallContext(options)))
            {
                yield return data;
            }
            
       
    }

    /// <summary>
    /// 获取调度数据
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<List<ProcessBaseData>> GetProcessDatas(ProcessProviderCommand command)
    {
        try
        {
            await ConnectGrpcServer();
            var result = await _connectGrpcService.RequestProcessDatas(command);
            return result.Data;
        }
        catch(Exception ex)
        {
            return new List<ProcessBaseData>();
        }
       
    }
    /// <summary>
    /// 添加调度任务
    /// </summary>
    /// <param name="command"></param>
    /// <returns></returns>
    public async Task<string> AddProcessJob(ProcessJobCommand command)
    {
        try
        {
            await ConnectGrpcServer();
            var result = await _connectGrpcService.AddProcessJob(command);
            return result.Data;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }
    /// <summary>
    /// 添加web控制
    /// </summary>
    /// <param name="control"></param>
    /// <returns></returns>
    /// <exception cref="NotImplementedException"></exception>
    public async Task<string> AddWebControl(WebControlModel control)
    {
        try
        {
            await ConnectGrpcServer();
            var result = await _connectGrpcService.AddWebControl(control);
            return result.Data;
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }






    #region 弃用

    public Task<GrpcReturn<string>> CheckNGResult(HkWriteInstruct data)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<string>> CommitChargeFMTResult(ChargeTrayResult result)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<string>> CommitFireWarn(IotEquipWarnDto iotEquipWarnDto)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<string>> CommitFmtMove(StageMoveInstruct moveInstruct)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<OCVCellMain>> CommitOcvResult(OCVTrayResult data)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<string>> CommitSelResult(HkWriteInstruct data)
    {
        throw new NotImplementedException();
    }


    public Task<GrpcReturn<string>> GetChargeFMTData(HkWriteInstruct hkWrite)
    {
        throw new NotImplementedException();
    }


    public Task<GrpcReturn<string>> GetReTestChargeFMT(HkWriteInstruct hkWrite)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<SelCellResult>> GetSelCellData(HkWriteInstruct data)
    {
        throw new NotImplementedException();
    }

    public Task<GrpcReturn<TrayCellStatus>> GetTrayCellStatus(TrayDefineInstruct trayDefineInstruct)
    {
        throw new NotImplementedException();
    }

    




    #endregion




}
